// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// ███╗   ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
// ████╗  ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
// ██╔██╗ ██║██║   ██║   ██║   ██║██║     █████╗
// ██║╚██╗██║██║   ██║   ██║   ██║██║     ██╔══╝
// ██║ ╚████║╚██████╔╝   ██║   ██║╚██████╗███████╗
// ╚═╝  ╚═══╝ ╚═════╝    ╚═╝   ╚═╝ ╚═════╝╚══════╝
// ------------------------------------------------
//
// This file is automatically generated.
// Please do not edit these files manually.
//
// ------------------------------------------------

#nullable restore

using Elastic.Clients.Elasticsearch.Serverless.Fluent;
using Elastic.Clients.Elasticsearch.Serverless.Serialization;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Elastic.Clients.Elasticsearch.Serverless.MachineLearning;

internal sealed partial class DatafeedConfigConverter : JsonConverter<DatafeedConfig>
{
	public override DatafeedConfig Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
	{
		if (reader.TokenType != JsonTokenType.StartObject)
			throw new JsonException("Unexpected JSON detected.");
		var variant = new DatafeedConfig();
		while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
		{
			if (reader.TokenType == JsonTokenType.PropertyName)
			{
				var property = reader.GetString();
				if (property == "aggregations" || property == "aggs")
				{
					variant.Aggregations = JsonSerializer.Deserialize<IDictionary<string, Elastic.Clients.Elasticsearch.Serverless.Aggregations.Aggregation>?>(ref reader, options);
					continue;
				}

				if (property == "chunking_config")
				{
					variant.ChunkingConfig = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfig?>(ref reader, options);
					continue;
				}

				if (property == "datafeed_id")
				{
					variant.DatafeedId = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Id?>(ref reader, options);
					continue;
				}

				if (property == "delayed_data_check_config")
				{
					variant.DelayedDataCheckConfig = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfig?>(ref reader, options);
					continue;
				}

				if (property == "frequency")
				{
					variant.Frequency = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Duration?>(ref reader, options);
					continue;
				}

				if (property == "indices" || property == "indexes")
				{
					variant.Indices = JsonSerializer.Deserialize<ICollection<string>?>(ref reader, options);
					continue;
				}

				if (property == "indices_options")
				{
					variant.IndicesOptions = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.IndicesOptions?>(ref reader, options);
					continue;
				}

				if (property == "job_id")
				{
					variant.JobId = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Id?>(ref reader, options);
					continue;
				}

				if (property == "max_empty_searches")
				{
					variant.MaxEmptySearches = JsonSerializer.Deserialize<int?>(ref reader, options);
					continue;
				}

				if (property == "query")
				{
					variant.Query = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.QueryDsl.Query?>(ref reader, options);
					continue;
				}

				if (property == "query_delay")
				{
					variant.QueryDelay = JsonSerializer.Deserialize<Elastic.Clients.Elasticsearch.Serverless.Duration?>(ref reader, options);
					continue;
				}

				if (property == "runtime_mappings")
				{
					variant.RuntimeMappings = JsonSerializer.Deserialize<IDictionary<Elastic.Clients.Elasticsearch.Serverless.Field, Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeField>?>(ref reader, options);
					continue;
				}

				if (property == "script_fields")
				{
					variant.ScriptFields = JsonSerializer.Deserialize<IDictionary<string, Elastic.Clients.Elasticsearch.Serverless.ScriptField>?>(ref reader, options);
					continue;
				}

				if (property == "scroll_size")
				{
					variant.ScrollSize = JsonSerializer.Deserialize<int?>(ref reader, options);
					continue;
				}
			}
		}

		return variant;
	}

	public override void Write(Utf8JsonWriter writer, DatafeedConfig value, JsonSerializerOptions options)
	{
		writer.WriteStartObject();
		if (value.Aggregations is not null)
		{
			writer.WritePropertyName("aggregations");
			JsonSerializer.Serialize(writer, value.Aggregations, options);
		}

		if (value.ChunkingConfig is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, value.ChunkingConfig, options);
		}

		if (value.DatafeedId is not null)
		{
			writer.WritePropertyName("datafeed_id");
			JsonSerializer.Serialize(writer, value.DatafeedId, options);
		}

		if (value.DelayedDataCheckConfig is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, value.DelayedDataCheckConfig, options);
		}

		if (value.Frequency is not null)
		{
			writer.WritePropertyName("frequency");
			JsonSerializer.Serialize(writer, value.Frequency, options);
		}

		if (value.Indices is not null)
		{
			writer.WritePropertyName("indices");
			JsonSerializer.Serialize(writer, value.Indices, options);
		}

		if (value.IndicesOptions is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, value.IndicesOptions, options);
		}

		if (value.JobId is not null)
		{
			writer.WritePropertyName("job_id");
			JsonSerializer.Serialize(writer, value.JobId, options);
		}

		if (value.MaxEmptySearches.HasValue)
		{
			writer.WritePropertyName("max_empty_searches");
			writer.WriteNumberValue(value.MaxEmptySearches.Value);
		}

		if (value.Query is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, value.Query, options);
		}

		if (value.QueryDelay is not null)
		{
			writer.WritePropertyName("query_delay");
			JsonSerializer.Serialize(writer, value.QueryDelay, options);
		}

		if (value.RuntimeMappings is not null)
		{
			writer.WritePropertyName("runtime_mappings");
			JsonSerializer.Serialize(writer, value.RuntimeMappings, options);
		}

		if (value.ScriptFields is not null)
		{
			writer.WritePropertyName("script_fields");
			JsonSerializer.Serialize(writer, value.ScriptFields, options);
		}

		if (value.ScrollSize.HasValue)
		{
			writer.WritePropertyName("scroll_size");
			writer.WriteNumberValue(value.ScrollSize.Value);
		}

		writer.WriteEndObject();
	}
}

[JsonConverter(typeof(DatafeedConfigConverter))]
public sealed partial class DatafeedConfig
{
	/// <summary>
	/// <para>If set, the datafeed performs aggregation searches. Support for aggregations is limited and should be used only with low cardinality data.</para>
	/// </summary>
	public IDictionary<string, Elastic.Clients.Elasticsearch.Serverless.Aggregations.Aggregation>? Aggregations { get; set; }

	/// <summary>
	/// <para>Datafeeds might be required to search over long time periods, for several months or years. This search is split into time chunks in order to ensure the load on Elasticsearch is managed. Chunking configuration controls how the size of these time chunks are calculated and is an advanced configuration option.</para>
	/// </summary>
	public Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfig? ChunkingConfig { get; set; }

	/// <summary>
	/// <para>A numerical character string that uniquely identifies the datafeed. This identifier can contain lowercase alphanumeric characters (a-z and 0-9), hyphens, and underscores. It must start and end with alphanumeric characters. The default value is the job identifier.</para>
	/// </summary>
	public Elastic.Clients.Elasticsearch.Serverless.Id? DatafeedId { get; set; }

	/// <summary>
	/// <para>Specifies whether the datafeed checks for missing data and the size of the window. The datafeed can optionally search over indices that have already been read in an effort to determine whether any data has subsequently been added to the index. If missing data is found, it is a good indication that the `query_delay` option is set too low and the data is being indexed after the datafeed has passed that moment in time. This check runs only on real-time datafeeds.</para>
	/// </summary>
	public Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfig? DelayedDataCheckConfig { get; set; }

	/// <summary>
	/// <para>The interval at which scheduled queries are made while the datafeed runs in real time. The default value is either the bucket span for short bucket spans, or, for longer bucket spans, a sensible fraction of the bucket span. For example: `150s`. When `frequency` is shorter than the bucket span, interim results for the last (partial) bucket are written then eventually overwritten by the full bucket results. If the datafeed uses aggregations, this value must be divisible by the interval of the date histogram aggregation.</para>
	/// </summary>
	public Elastic.Clients.Elasticsearch.Serverless.Duration? Frequency { get; set; }

	/// <summary>
	/// <para>An array of index names. Wildcards are supported. If any indices are in remote clusters, the machine learning nodes must have the `remote_cluster_client` role.</para>
	/// </summary>
	public ICollection<string>? Indices { get; set; }

	/// <summary>
	/// <para>Specifies index expansion options that are used during search.</para>
	/// </summary>
	public Elastic.Clients.Elasticsearch.Serverless.IndicesOptions? IndicesOptions { get; set; }
	public Elastic.Clients.Elasticsearch.Serverless.Id? JobId { get; set; }

	/// <summary>
	/// <para>If a real-time datafeed has never seen any data (including during any initial training period) then it will automatically stop itself and close its associated job after this many real-time searches that return no documents. In other words, it will stop after `frequency` times `max_empty_searches` of real-time operation. If not set then a datafeed with no end time that sees no data will remain started until it is explicitly stopped.</para>
	/// </summary>
	public int? MaxEmptySearches { get; set; }

	/// <summary>
	/// <para>The Elasticsearch query domain-specific language (DSL). This value corresponds to the query object in an Elasticsearch search POST body. All the options that are supported by Elasticsearch can be used, as this object is passed verbatim to Elasticsearch.</para>
	/// </summary>
	public Elastic.Clients.Elasticsearch.Serverless.QueryDsl.Query? Query { get; set; }

	/// <summary>
	/// <para>The number of seconds behind real time that data is queried. For example, if data from 10:04 a.m. might not be searchable in Elasticsearch until 10:06 a.m., set this property to 120 seconds. The default value is randomly selected between `60s` and `120s`. This randomness improves the query performance when there are multiple jobs running on the same node.</para>
	/// </summary>
	public Elastic.Clients.Elasticsearch.Serverless.Duration? QueryDelay { get; set; }

	/// <summary>
	/// <para>Specifies runtime fields for the datafeed search.</para>
	/// </summary>
	public IDictionary<Elastic.Clients.Elasticsearch.Serverless.Field, Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeField>? RuntimeMappings { get; set; }

	/// <summary>
	/// <para>Specifies scripts that evaluate custom expressions and returns script fields to the datafeed. The detector configuration objects in a job can contain functions that use these script fields.</para>
	/// </summary>
	public IDictionary<string, Elastic.Clients.Elasticsearch.Serverless.ScriptField>? ScriptFields { get; set; }

	/// <summary>
	/// <para>The size parameter that is used in Elasticsearch searches when the datafeed does not use aggregations. The maximum value is the value of `index.max_result_window`, which is 10,000 by default.</para>
	/// </summary>
	public int? ScrollSize { get; set; }
}

public sealed partial class DatafeedConfigDescriptor<TDocument> : SerializableDescriptor<DatafeedConfigDescriptor<TDocument>>
{
	internal DatafeedConfigDescriptor(Action<DatafeedConfigDescriptor<TDocument>> configure) => configure.Invoke(this);

	public DatafeedConfigDescriptor() : base()
	{
	}

	private IDictionary<string, Elastic.Clients.Elasticsearch.Serverless.Aggregations.AggregationDescriptor<TDocument>> AggregationsValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfig? ChunkingConfigValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfigDescriptor ChunkingConfigDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfigDescriptor> ChunkingConfigDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Id? DatafeedIdValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfig? DelayedDataCheckConfigValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfigDescriptor DelayedDataCheckConfigDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfigDescriptor> DelayedDataCheckConfigDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Duration? FrequencyValue { get; set; }
	private ICollection<string>? IndicesValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.IndicesOptions? IndicesOptionsValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.IndicesOptionsDescriptor IndicesOptionsDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Serverless.IndicesOptionsDescriptor> IndicesOptionsDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Id? JobIdValue { get; set; }
	private int? MaxEmptySearchesValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.QueryDsl.Query? QueryValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.QueryDsl.QueryDescriptor<TDocument> QueryDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Serverless.QueryDsl.QueryDescriptor<TDocument>> QueryDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Duration? QueryDelayValue { get; set; }
	private IDictionary<Elastic.Clients.Elasticsearch.Serverless.Field, Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldDescriptor<TDocument>> RuntimeMappingsValue { get; set; }
	private IDictionary<string, Elastic.Clients.Elasticsearch.Serverless.ScriptFieldDescriptor> ScriptFieldsValue { get; set; }
	private int? ScrollSizeValue { get; set; }

	/// <summary>
	/// <para>If set, the datafeed performs aggregation searches. Support for aggregations is limited and should be used only with low cardinality data.</para>
	/// </summary>
	public DatafeedConfigDescriptor<TDocument> Aggregations(Func<FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Serverless.Aggregations.AggregationDescriptor<TDocument>>, FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Serverless.Aggregations.AggregationDescriptor<TDocument>>> selector)
	{
		AggregationsValue = selector?.Invoke(new FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Serverless.Aggregations.AggregationDescriptor<TDocument>>());
		return Self;
	}

	/// <summary>
	/// <para>Datafeeds might be required to search over long time periods, for several months or years. This search is split into time chunks in order to ensure the load on Elasticsearch is managed. Chunking configuration controls how the size of these time chunks are calculated and is an advanced configuration option.</para>
	/// </summary>
	public DatafeedConfigDescriptor<TDocument> ChunkingConfig(Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfig? chunkingConfig)
	{
		ChunkingConfigDescriptor = null;
		ChunkingConfigDescriptorAction = null;
		ChunkingConfigValue = chunkingConfig;
		return Self;
	}

	public DatafeedConfigDescriptor<TDocument> ChunkingConfig(Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfigDescriptor descriptor)
	{
		ChunkingConfigValue = null;
		ChunkingConfigDescriptorAction = null;
		ChunkingConfigDescriptor = descriptor;
		return Self;
	}

	public DatafeedConfigDescriptor<TDocument> ChunkingConfig(Action<Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfigDescriptor> configure)
	{
		ChunkingConfigValue = null;
		ChunkingConfigDescriptor = null;
		ChunkingConfigDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>A numerical character string that uniquely identifies the datafeed. This identifier can contain lowercase alphanumeric characters (a-z and 0-9), hyphens, and underscores. It must start and end with alphanumeric characters. The default value is the job identifier.</para>
	/// </summary>
	public DatafeedConfigDescriptor<TDocument> DatafeedId(Elastic.Clients.Elasticsearch.Serverless.Id? datafeedId)
	{
		DatafeedIdValue = datafeedId;
		return Self;
	}

	/// <summary>
	/// <para>Specifies whether the datafeed checks for missing data and the size of the window. The datafeed can optionally search over indices that have already been read in an effort to determine whether any data has subsequently been added to the index. If missing data is found, it is a good indication that the `query_delay` option is set too low and the data is being indexed after the datafeed has passed that moment in time. This check runs only on real-time datafeeds.</para>
	/// </summary>
	public DatafeedConfigDescriptor<TDocument> DelayedDataCheckConfig(Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfig? delayedDataCheckConfig)
	{
		DelayedDataCheckConfigDescriptor = null;
		DelayedDataCheckConfigDescriptorAction = null;
		DelayedDataCheckConfigValue = delayedDataCheckConfig;
		return Self;
	}

	public DatafeedConfigDescriptor<TDocument> DelayedDataCheckConfig(Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfigDescriptor descriptor)
	{
		DelayedDataCheckConfigValue = null;
		DelayedDataCheckConfigDescriptorAction = null;
		DelayedDataCheckConfigDescriptor = descriptor;
		return Self;
	}

	public DatafeedConfigDescriptor<TDocument> DelayedDataCheckConfig(Action<Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfigDescriptor> configure)
	{
		DelayedDataCheckConfigValue = null;
		DelayedDataCheckConfigDescriptor = null;
		DelayedDataCheckConfigDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>The interval at which scheduled queries are made while the datafeed runs in real time. The default value is either the bucket span for short bucket spans, or, for longer bucket spans, a sensible fraction of the bucket span. For example: `150s`. When `frequency` is shorter than the bucket span, interim results for the last (partial) bucket are written then eventually overwritten by the full bucket results. If the datafeed uses aggregations, this value must be divisible by the interval of the date histogram aggregation.</para>
	/// </summary>
	public DatafeedConfigDescriptor<TDocument> Frequency(Elastic.Clients.Elasticsearch.Serverless.Duration? frequency)
	{
		FrequencyValue = frequency;
		return Self;
	}

	/// <summary>
	/// <para>An array of index names. Wildcards are supported. If any indices are in remote clusters, the machine learning nodes must have the `remote_cluster_client` role.</para>
	/// </summary>
	public DatafeedConfigDescriptor<TDocument> Indices(ICollection<string>? indices)
	{
		IndicesValue = indices;
		return Self;
	}

	/// <summary>
	/// <para>Specifies index expansion options that are used during search.</para>
	/// </summary>
	public DatafeedConfigDescriptor<TDocument> IndicesOptions(Elastic.Clients.Elasticsearch.Serverless.IndicesOptions? indicesOptions)
	{
		IndicesOptionsDescriptor = null;
		IndicesOptionsDescriptorAction = null;
		IndicesOptionsValue = indicesOptions;
		return Self;
	}

	public DatafeedConfigDescriptor<TDocument> IndicesOptions(Elastic.Clients.Elasticsearch.Serverless.IndicesOptionsDescriptor descriptor)
	{
		IndicesOptionsValue = null;
		IndicesOptionsDescriptorAction = null;
		IndicesOptionsDescriptor = descriptor;
		return Self;
	}

	public DatafeedConfigDescriptor<TDocument> IndicesOptions(Action<Elastic.Clients.Elasticsearch.Serverless.IndicesOptionsDescriptor> configure)
	{
		IndicesOptionsValue = null;
		IndicesOptionsDescriptor = null;
		IndicesOptionsDescriptorAction = configure;
		return Self;
	}

	public DatafeedConfigDescriptor<TDocument> JobId(Elastic.Clients.Elasticsearch.Serverless.Id? jobId)
	{
		JobIdValue = jobId;
		return Self;
	}

	/// <summary>
	/// <para>If a real-time datafeed has never seen any data (including during any initial training period) then it will automatically stop itself and close its associated job after this many real-time searches that return no documents. In other words, it will stop after `frequency` times `max_empty_searches` of real-time operation. If not set then a datafeed with no end time that sees no data will remain started until it is explicitly stopped.</para>
	/// </summary>
	public DatafeedConfigDescriptor<TDocument> MaxEmptySearches(int? maxEmptySearches)
	{
		MaxEmptySearchesValue = maxEmptySearches;
		return Self;
	}

	/// <summary>
	/// <para>The Elasticsearch query domain-specific language (DSL). This value corresponds to the query object in an Elasticsearch search POST body. All the options that are supported by Elasticsearch can be used, as this object is passed verbatim to Elasticsearch.</para>
	/// </summary>
	public DatafeedConfigDescriptor<TDocument> Query(Elastic.Clients.Elasticsearch.Serverless.QueryDsl.Query? query)
	{
		QueryDescriptor = null;
		QueryDescriptorAction = null;
		QueryValue = query;
		return Self;
	}

	public DatafeedConfigDescriptor<TDocument> Query(Elastic.Clients.Elasticsearch.Serverless.QueryDsl.QueryDescriptor<TDocument> descriptor)
	{
		QueryValue = null;
		QueryDescriptorAction = null;
		QueryDescriptor = descriptor;
		return Self;
	}

	public DatafeedConfigDescriptor<TDocument> Query(Action<Elastic.Clients.Elasticsearch.Serverless.QueryDsl.QueryDescriptor<TDocument>> configure)
	{
		QueryValue = null;
		QueryDescriptor = null;
		QueryDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>The number of seconds behind real time that data is queried. For example, if data from 10:04 a.m. might not be searchable in Elasticsearch until 10:06 a.m., set this property to 120 seconds. The default value is randomly selected between `60s` and `120s`. This randomness improves the query performance when there are multiple jobs running on the same node.</para>
	/// </summary>
	public DatafeedConfigDescriptor<TDocument> QueryDelay(Elastic.Clients.Elasticsearch.Serverless.Duration? queryDelay)
	{
		QueryDelayValue = queryDelay;
		return Self;
	}

	/// <summary>
	/// <para>Specifies runtime fields for the datafeed search.</para>
	/// </summary>
	public DatafeedConfigDescriptor<TDocument> RuntimeMappings(Func<FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Serverless.Field, Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldDescriptor<TDocument>>, FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Serverless.Field, Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldDescriptor<TDocument>>> selector)
	{
		RuntimeMappingsValue = selector?.Invoke(new FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Serverless.Field, Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldDescriptor<TDocument>>());
		return Self;
	}

	/// <summary>
	/// <para>Specifies scripts that evaluate custom expressions and returns script fields to the datafeed. The detector configuration objects in a job can contain functions that use these script fields.</para>
	/// </summary>
	public DatafeedConfigDescriptor<TDocument> ScriptFields(Func<FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Serverless.ScriptFieldDescriptor>, FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Serverless.ScriptFieldDescriptor>> selector)
	{
		ScriptFieldsValue = selector?.Invoke(new FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Serverless.ScriptFieldDescriptor>());
		return Self;
	}

	/// <summary>
	/// <para>The size parameter that is used in Elasticsearch searches when the datafeed does not use aggregations. The maximum value is the value of `index.max_result_window`, which is 10,000 by default.</para>
	/// </summary>
	public DatafeedConfigDescriptor<TDocument> ScrollSize(int? scrollSize)
	{
		ScrollSizeValue = scrollSize;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (AggregationsValue is not null)
		{
			writer.WritePropertyName("aggregations");
			JsonSerializer.Serialize(writer, AggregationsValue, options);
		}

		if (ChunkingConfigDescriptor is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, ChunkingConfigDescriptor, options);
		}
		else if (ChunkingConfigDescriptorAction is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfigDescriptor(ChunkingConfigDescriptorAction), options);
		}
		else if (ChunkingConfigValue is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, ChunkingConfigValue, options);
		}

		if (DatafeedIdValue is not null)
		{
			writer.WritePropertyName("datafeed_id");
			JsonSerializer.Serialize(writer, DatafeedIdValue, options);
		}

		if (DelayedDataCheckConfigDescriptor is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, DelayedDataCheckConfigDescriptor, options);
		}
		else if (DelayedDataCheckConfigDescriptorAction is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfigDescriptor(DelayedDataCheckConfigDescriptorAction), options);
		}
		else if (DelayedDataCheckConfigValue is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, DelayedDataCheckConfigValue, options);
		}

		if (FrequencyValue is not null)
		{
			writer.WritePropertyName("frequency");
			JsonSerializer.Serialize(writer, FrequencyValue, options);
		}

		if (IndicesValue is not null)
		{
			writer.WritePropertyName("indices");
			JsonSerializer.Serialize(writer, IndicesValue, options);
		}

		if (IndicesOptionsDescriptor is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, IndicesOptionsDescriptor, options);
		}
		else if (IndicesOptionsDescriptorAction is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Serverless.IndicesOptionsDescriptor(IndicesOptionsDescriptorAction), options);
		}
		else if (IndicesOptionsValue is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, IndicesOptionsValue, options);
		}

		if (JobIdValue is not null)
		{
			writer.WritePropertyName("job_id");
			JsonSerializer.Serialize(writer, JobIdValue, options);
		}

		if (MaxEmptySearchesValue.HasValue)
		{
			writer.WritePropertyName("max_empty_searches");
			writer.WriteNumberValue(MaxEmptySearchesValue.Value);
		}

		if (QueryDescriptor is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, QueryDescriptor, options);
		}
		else if (QueryDescriptorAction is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Serverless.QueryDsl.QueryDescriptor<TDocument>(QueryDescriptorAction), options);
		}
		else if (QueryValue is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, QueryValue, options);
		}

		if (QueryDelayValue is not null)
		{
			writer.WritePropertyName("query_delay");
			JsonSerializer.Serialize(writer, QueryDelayValue, options);
		}

		if (RuntimeMappingsValue is not null)
		{
			writer.WritePropertyName("runtime_mappings");
			JsonSerializer.Serialize(writer, RuntimeMappingsValue, options);
		}

		if (ScriptFieldsValue is not null)
		{
			writer.WritePropertyName("script_fields");
			JsonSerializer.Serialize(writer, ScriptFieldsValue, options);
		}

		if (ScrollSizeValue.HasValue)
		{
			writer.WritePropertyName("scroll_size");
			writer.WriteNumberValue(ScrollSizeValue.Value);
		}

		writer.WriteEndObject();
	}
}

public sealed partial class DatafeedConfigDescriptor : SerializableDescriptor<DatafeedConfigDescriptor>
{
	internal DatafeedConfigDescriptor(Action<DatafeedConfigDescriptor> configure) => configure.Invoke(this);

	public DatafeedConfigDescriptor() : base()
	{
	}

	private IDictionary<string, Elastic.Clients.Elasticsearch.Serverless.Aggregations.AggregationDescriptor> AggregationsValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfig? ChunkingConfigValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfigDescriptor ChunkingConfigDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfigDescriptor> ChunkingConfigDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Id? DatafeedIdValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfig? DelayedDataCheckConfigValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfigDescriptor DelayedDataCheckConfigDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfigDescriptor> DelayedDataCheckConfigDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Duration? FrequencyValue { get; set; }
	private ICollection<string>? IndicesValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.IndicesOptions? IndicesOptionsValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.IndicesOptionsDescriptor IndicesOptionsDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Serverless.IndicesOptionsDescriptor> IndicesOptionsDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Id? JobIdValue { get; set; }
	private int? MaxEmptySearchesValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.QueryDsl.Query? QueryValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.QueryDsl.QueryDescriptor QueryDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Serverless.QueryDsl.QueryDescriptor> QueryDescriptorAction { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Duration? QueryDelayValue { get; set; }
	private IDictionary<Elastic.Clients.Elasticsearch.Serverless.Field, Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldDescriptor> RuntimeMappingsValue { get; set; }
	private IDictionary<string, Elastic.Clients.Elasticsearch.Serverless.ScriptFieldDescriptor> ScriptFieldsValue { get; set; }
	private int? ScrollSizeValue { get; set; }

	/// <summary>
	/// <para>If set, the datafeed performs aggregation searches. Support for aggregations is limited and should be used only with low cardinality data.</para>
	/// </summary>
	public DatafeedConfigDescriptor Aggregations(Func<FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Serverless.Aggregations.AggregationDescriptor>, FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Serverless.Aggregations.AggregationDescriptor>> selector)
	{
		AggregationsValue = selector?.Invoke(new FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Serverless.Aggregations.AggregationDescriptor>());
		return Self;
	}

	/// <summary>
	/// <para>Datafeeds might be required to search over long time periods, for several months or years. This search is split into time chunks in order to ensure the load on Elasticsearch is managed. Chunking configuration controls how the size of these time chunks are calculated and is an advanced configuration option.</para>
	/// </summary>
	public DatafeedConfigDescriptor ChunkingConfig(Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfig? chunkingConfig)
	{
		ChunkingConfigDescriptor = null;
		ChunkingConfigDescriptorAction = null;
		ChunkingConfigValue = chunkingConfig;
		return Self;
	}

	public DatafeedConfigDescriptor ChunkingConfig(Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfigDescriptor descriptor)
	{
		ChunkingConfigValue = null;
		ChunkingConfigDescriptorAction = null;
		ChunkingConfigDescriptor = descriptor;
		return Self;
	}

	public DatafeedConfigDescriptor ChunkingConfig(Action<Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfigDescriptor> configure)
	{
		ChunkingConfigValue = null;
		ChunkingConfigDescriptor = null;
		ChunkingConfigDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>A numerical character string that uniquely identifies the datafeed. This identifier can contain lowercase alphanumeric characters (a-z and 0-9), hyphens, and underscores. It must start and end with alphanumeric characters. The default value is the job identifier.</para>
	/// </summary>
	public DatafeedConfigDescriptor DatafeedId(Elastic.Clients.Elasticsearch.Serverless.Id? datafeedId)
	{
		DatafeedIdValue = datafeedId;
		return Self;
	}

	/// <summary>
	/// <para>Specifies whether the datafeed checks for missing data and the size of the window. The datafeed can optionally search over indices that have already been read in an effort to determine whether any data has subsequently been added to the index. If missing data is found, it is a good indication that the `query_delay` option is set too low and the data is being indexed after the datafeed has passed that moment in time. This check runs only on real-time datafeeds.</para>
	/// </summary>
	public DatafeedConfigDescriptor DelayedDataCheckConfig(Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfig? delayedDataCheckConfig)
	{
		DelayedDataCheckConfigDescriptor = null;
		DelayedDataCheckConfigDescriptorAction = null;
		DelayedDataCheckConfigValue = delayedDataCheckConfig;
		return Self;
	}

	public DatafeedConfigDescriptor DelayedDataCheckConfig(Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfigDescriptor descriptor)
	{
		DelayedDataCheckConfigValue = null;
		DelayedDataCheckConfigDescriptorAction = null;
		DelayedDataCheckConfigDescriptor = descriptor;
		return Self;
	}

	public DatafeedConfigDescriptor DelayedDataCheckConfig(Action<Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfigDescriptor> configure)
	{
		DelayedDataCheckConfigValue = null;
		DelayedDataCheckConfigDescriptor = null;
		DelayedDataCheckConfigDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>The interval at which scheduled queries are made while the datafeed runs in real time. The default value is either the bucket span for short bucket spans, or, for longer bucket spans, a sensible fraction of the bucket span. For example: `150s`. When `frequency` is shorter than the bucket span, interim results for the last (partial) bucket are written then eventually overwritten by the full bucket results. If the datafeed uses aggregations, this value must be divisible by the interval of the date histogram aggregation.</para>
	/// </summary>
	public DatafeedConfigDescriptor Frequency(Elastic.Clients.Elasticsearch.Serverless.Duration? frequency)
	{
		FrequencyValue = frequency;
		return Self;
	}

	/// <summary>
	/// <para>An array of index names. Wildcards are supported. If any indices are in remote clusters, the machine learning nodes must have the `remote_cluster_client` role.</para>
	/// </summary>
	public DatafeedConfigDescriptor Indices(ICollection<string>? indices)
	{
		IndicesValue = indices;
		return Self;
	}

	/// <summary>
	/// <para>Specifies index expansion options that are used during search.</para>
	/// </summary>
	public DatafeedConfigDescriptor IndicesOptions(Elastic.Clients.Elasticsearch.Serverless.IndicesOptions? indicesOptions)
	{
		IndicesOptionsDescriptor = null;
		IndicesOptionsDescriptorAction = null;
		IndicesOptionsValue = indicesOptions;
		return Self;
	}

	public DatafeedConfigDescriptor IndicesOptions(Elastic.Clients.Elasticsearch.Serverless.IndicesOptionsDescriptor descriptor)
	{
		IndicesOptionsValue = null;
		IndicesOptionsDescriptorAction = null;
		IndicesOptionsDescriptor = descriptor;
		return Self;
	}

	public DatafeedConfigDescriptor IndicesOptions(Action<Elastic.Clients.Elasticsearch.Serverless.IndicesOptionsDescriptor> configure)
	{
		IndicesOptionsValue = null;
		IndicesOptionsDescriptor = null;
		IndicesOptionsDescriptorAction = configure;
		return Self;
	}

	public DatafeedConfigDescriptor JobId(Elastic.Clients.Elasticsearch.Serverless.Id? jobId)
	{
		JobIdValue = jobId;
		return Self;
	}

	/// <summary>
	/// <para>If a real-time datafeed has never seen any data (including during any initial training period) then it will automatically stop itself and close its associated job after this many real-time searches that return no documents. In other words, it will stop after `frequency` times `max_empty_searches` of real-time operation. If not set then a datafeed with no end time that sees no data will remain started until it is explicitly stopped.</para>
	/// </summary>
	public DatafeedConfigDescriptor MaxEmptySearches(int? maxEmptySearches)
	{
		MaxEmptySearchesValue = maxEmptySearches;
		return Self;
	}

	/// <summary>
	/// <para>The Elasticsearch query domain-specific language (DSL). This value corresponds to the query object in an Elasticsearch search POST body. All the options that are supported by Elasticsearch can be used, as this object is passed verbatim to Elasticsearch.</para>
	/// </summary>
	public DatafeedConfigDescriptor Query(Elastic.Clients.Elasticsearch.Serverless.QueryDsl.Query? query)
	{
		QueryDescriptor = null;
		QueryDescriptorAction = null;
		QueryValue = query;
		return Self;
	}

	public DatafeedConfigDescriptor Query(Elastic.Clients.Elasticsearch.Serverless.QueryDsl.QueryDescriptor descriptor)
	{
		QueryValue = null;
		QueryDescriptorAction = null;
		QueryDescriptor = descriptor;
		return Self;
	}

	public DatafeedConfigDescriptor Query(Action<Elastic.Clients.Elasticsearch.Serverless.QueryDsl.QueryDescriptor> configure)
	{
		QueryValue = null;
		QueryDescriptor = null;
		QueryDescriptorAction = configure;
		return Self;
	}

	/// <summary>
	/// <para>The number of seconds behind real time that data is queried. For example, if data from 10:04 a.m. might not be searchable in Elasticsearch until 10:06 a.m., set this property to 120 seconds. The default value is randomly selected between `60s` and `120s`. This randomness improves the query performance when there are multiple jobs running on the same node.</para>
	/// </summary>
	public DatafeedConfigDescriptor QueryDelay(Elastic.Clients.Elasticsearch.Serverless.Duration? queryDelay)
	{
		QueryDelayValue = queryDelay;
		return Self;
	}

	/// <summary>
	/// <para>Specifies runtime fields for the datafeed search.</para>
	/// </summary>
	public DatafeedConfigDescriptor RuntimeMappings(Func<FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Serverless.Field, Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldDescriptor>, FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Serverless.Field, Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldDescriptor>> selector)
	{
		RuntimeMappingsValue = selector?.Invoke(new FluentDescriptorDictionary<Elastic.Clients.Elasticsearch.Serverless.Field, Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldDescriptor>());
		return Self;
	}

	/// <summary>
	/// <para>Specifies scripts that evaluate custom expressions and returns script fields to the datafeed. The detector configuration objects in a job can contain functions that use these script fields.</para>
	/// </summary>
	public DatafeedConfigDescriptor ScriptFields(Func<FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Serverless.ScriptFieldDescriptor>, FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Serverless.ScriptFieldDescriptor>> selector)
	{
		ScriptFieldsValue = selector?.Invoke(new FluentDescriptorDictionary<string, Elastic.Clients.Elasticsearch.Serverless.ScriptFieldDescriptor>());
		return Self;
	}

	/// <summary>
	/// <para>The size parameter that is used in Elasticsearch searches when the datafeed does not use aggregations. The maximum value is the value of `index.max_result_window`, which is 10,000 by default.</para>
	/// </summary>
	public DatafeedConfigDescriptor ScrollSize(int? scrollSize)
	{
		ScrollSizeValue = scrollSize;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (AggregationsValue is not null)
		{
			writer.WritePropertyName("aggregations");
			JsonSerializer.Serialize(writer, AggregationsValue, options);
		}

		if (ChunkingConfigDescriptor is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, ChunkingConfigDescriptor, options);
		}
		else if (ChunkingConfigDescriptorAction is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Serverless.MachineLearning.ChunkingConfigDescriptor(ChunkingConfigDescriptorAction), options);
		}
		else if (ChunkingConfigValue is not null)
		{
			writer.WritePropertyName("chunking_config");
			JsonSerializer.Serialize(writer, ChunkingConfigValue, options);
		}

		if (DatafeedIdValue is not null)
		{
			writer.WritePropertyName("datafeed_id");
			JsonSerializer.Serialize(writer, DatafeedIdValue, options);
		}

		if (DelayedDataCheckConfigDescriptor is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, DelayedDataCheckConfigDescriptor, options);
		}
		else if (DelayedDataCheckConfigDescriptorAction is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Serverless.MachineLearning.DelayedDataCheckConfigDescriptor(DelayedDataCheckConfigDescriptorAction), options);
		}
		else if (DelayedDataCheckConfigValue is not null)
		{
			writer.WritePropertyName("delayed_data_check_config");
			JsonSerializer.Serialize(writer, DelayedDataCheckConfigValue, options);
		}

		if (FrequencyValue is not null)
		{
			writer.WritePropertyName("frequency");
			JsonSerializer.Serialize(writer, FrequencyValue, options);
		}

		if (IndicesValue is not null)
		{
			writer.WritePropertyName("indices");
			JsonSerializer.Serialize(writer, IndicesValue, options);
		}

		if (IndicesOptionsDescriptor is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, IndicesOptionsDescriptor, options);
		}
		else if (IndicesOptionsDescriptorAction is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Serverless.IndicesOptionsDescriptor(IndicesOptionsDescriptorAction), options);
		}
		else if (IndicesOptionsValue is not null)
		{
			writer.WritePropertyName("indices_options");
			JsonSerializer.Serialize(writer, IndicesOptionsValue, options);
		}

		if (JobIdValue is not null)
		{
			writer.WritePropertyName("job_id");
			JsonSerializer.Serialize(writer, JobIdValue, options);
		}

		if (MaxEmptySearchesValue.HasValue)
		{
			writer.WritePropertyName("max_empty_searches");
			writer.WriteNumberValue(MaxEmptySearchesValue.Value);
		}

		if (QueryDescriptor is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, QueryDescriptor, options);
		}
		else if (QueryDescriptorAction is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Serverless.QueryDsl.QueryDescriptor(QueryDescriptorAction), options);
		}
		else if (QueryValue is not null)
		{
			writer.WritePropertyName("query");
			JsonSerializer.Serialize(writer, QueryValue, options);
		}

		if (QueryDelayValue is not null)
		{
			writer.WritePropertyName("query_delay");
			JsonSerializer.Serialize(writer, QueryDelayValue, options);
		}

		if (RuntimeMappingsValue is not null)
		{
			writer.WritePropertyName("runtime_mappings");
			JsonSerializer.Serialize(writer, RuntimeMappingsValue, options);
		}

		if (ScriptFieldsValue is not null)
		{
			writer.WritePropertyName("script_fields");
			JsonSerializer.Serialize(writer, ScriptFieldsValue, options);
		}

		if (ScrollSizeValue.HasValue)
		{
			writer.WritePropertyName("scroll_size");
			writer.WriteNumberValue(ScrollSizeValue.Value);
		}

		writer.WriteEndObject();
	}
}